package com.sos.core
{
	
	import com.sos.core.cards.Deck;
	import com.sos.core.game.GameList;
	import com.sos.logging.Dumper;
	import com.sos.logging.IDumpable;
	
	public class User extends Player implements IDumpable
	{
		
		// -------------------------------------------------------------------------------
		// CONSTANTS
		// -------------------------------------------------------------------------------	
		
		// Property names
		
		protected static const 	PROPERTY_SESSION_TOKEN:String		= "sessionToken";
		protected static const 	PROPERTY_DECK_SIZE:String			= "deckSize";
		protected static const 	PROPERTY_FRIEND_LIST:String			= "friendList";
		protected static const 	PROPERTY_GAME_LIST:String			= "gameList";
		
		// -------------------------------------------------------------------------------
		// FIELDS
		// -------------------------------------------------------------------------------
		
		private var _deckSize:int;			// LT_TODO: eliminare e infilare dentro GameOptions
		private var _sessionToken:String;
		private var _friends:PlayerList = new PlayerList();
		private var _games:GameList = new GameList();
		
		// -------------------------------------------------------------------------------
		// CONSTRUCTOR
		// -------------------------------------------------------------------------------
		
		public function User(data:Object = null)
		{
			// Clear
			clear();
			// If data is provided, initializes the instance
			if (data != null) load(data);
		}
		
		// -------------------------------------------------------------------------------
		// PROPERTIES
		// -------------------------------------------------------------------------------
		
		public function get sessionToken():String
		{
			return _sessionToken;
		}
		
		public function get deckSize():int
		{
			return _deckSize;
		}
		
		public function get isLoggedIn():Boolean
		{
			// return loaded;
			return _id != DataObject.INVALID_ID;
		}
		
		public function get friends():PlayerList
		{
			return _friends;
		}
		
		public function get games():GameList
		{
			return _games;
		}

		// -------------------------------------------------------------------------------
		// PRIVATE METHODS
		// -------------------------------------------------------------------------------
		
		// DataObject implementation
		
		override protected function validate(data:Object):void
		{
			// Ancestor call
			super.validate(data);
			// Required fields
			if (!data.hasOwnProperty(JSON_PROPERTY_FIRST_NAME))	throwLoadMissingPropError(JSON_PROPERTY_FIRST_NAME);
			if (!data.hasOwnProperty(JSON_PROPERTY_LAST_NAME))	throwLoadMissingPropError(JSON_PROPERTY_LAST_NAME);
			if (!data.hasOwnProperty(JSON_PROPERTY_EMAIL))		throwLoadMissingPropError(JSON_PROPERTY_EMAIL);
		}
		
		override protected function fill(data:Object):void
		{
			// Ancestor
			super.fill(data);
			// Optional fields
			if (data.hasOwnProperty(PROPERTY_SESSION_TOKEN))	_sessionToken = data[PROPERTY_SESSION_TOKEN];
			if (data.hasOwnProperty(PROPERTY_DECK_SIZE)) 		_deckSize 	  = data[PROPERTY_DECK_SIZE];
			// Friend list handling
			if (data.hasOwnProperty(PROPERTY_FRIEND_LIST))
			{
				_friends.load(data[PROPERTY_FRIEND_LIST]);
			}
			// Game list handling
			if (data.hasOwnProperty(PROPERTY_GAME_LIST))
			{
				_games.load(data[PROPERTY_GAME_LIST]);
			}
		}


		// -------------------------------------------------------------------------------
		// PUBLIC METHODS
		// -------------------------------------------------------------------------------

		public function updateFriends(playerList:PlayerList):void
		{
			_friends.clear();
			_friends.copy(playerList);
		}
		
		public function updateGames(gameList:GameList):void
		{
			_games.clear();
			_games.copy(gameList);
		}
		
		override public function equals(player:Player):Boolean
		{
			if (player is User && super.equals(player))
			{
				// User cast
				var user:User = player as User;
				// Check User properties
				return 	_id				== user.id			&&
						_deckSize		== user.deckSize	&&
						_sessionToken	== user.sessionToken;
			}
			return false;
		}
		
		override public function copy(player:Player):void
		{	
			// Ancestor copy
			super.copy(player);
			// User cast
			var user:User = player as User;
			if (user != null)
			{
				// Copy valus
				_deckSize		= user.deckSize;
				_sessionToken	= user.sessionToken;
				// Copy objects
				_friends.copy(user.friends);
				_games.copy(user.games);
			}
		}
		
		override public function clone():Player
		{
			var user:User = new User();
			user.copy(this);
			return user;
		}
		
		override public function clear():void
		{
			// Ancestor
			super.clear();
			// Clear data
			_sessionToken	= "";
			_deckSize		= Deck.REQUIRED_ACTION_CARDS;
			// Clear obejcts
			_friends.clear();
			_games.clear();
		}
		
		public function toString():String
		{
			return _username + "(id: " + _id + ")";
		}
		
		override public function dump(source:Array = null, indentDepth:int = 0):Array
		{
			return Dumper.dump(this, null, source, indentDepth);
		}
		
	}
}